package scripts;

import bot.ScriptMethods;
import java.util.Arrays;
import javax.swing.JOptionPane;
import javax.swing.*;
import java.awt.*;

public class ARSFighter extends ScriptMethods implements Runnable {

	public boolean scriptRunning = false;
	public Thread scriptThread;
	private int[] foodIDs = { 350, 352, 362, 364, 367, 370, 373, 546, 555, 551,
			553, 355, 359, 357, 326, 327, 328, 329, 330, 332, 334, 335, 336,
			337, 750, 346, 249, 257, 258, 259, 261, 262, 263, 210 };
	private int[] boneIDs = { 20, 413, 604, 814 };
	private int[] IDs = { 65 };
	private int[] pickupIDs = { 777 };
	private int eatAt;
	private boolean walkback;
	private int walkbackXmin;
	private int walkbackXmax;
	private int walkbackYmin;
	private int walkbackYmax;
	private int origX;
	private int origY;

	public void start() {
		System.gc();

		getAccountSettings();

		String nids = JOptionPane.showInputDialog("Enter NPC IDs (multiple IDs separated with , no spaces): "); 
		if (!nids.equals("") || !nids.equals(null)) {
			IDs = stringToIntArray(nids);
		}

		String pids = JOptionPane.showInputDialog("Enter item IDs to pick up: "); 
		if (!pids.equals("") || !pids.equals(null)) {
			pickupIDs = stringToIntArray(pids);
		}

		String hp = JOptionPane.showInputDialog("Enter hits to eat at: "); 
		if (!hp.equals("") || !hp.equals(null)) {
			eatAt = Integer.parseInt(hp);
		} else {
			eatAt = 20;
		}

		try {
			if (isLoggedIn()) {
				walkback = true;
				walkbackXmin = (ourPlayerX() - 20);
				walkbackXmax = (ourPlayerX() + 20);
				walkbackYmin = (ourPlayerY() - 20);
				walkbackYmax = (ourPlayerY() + 20);
				origX = ourPlayerX();
				origY = ourPlayerY();
			} else {
				walkback = false;
			}
		} catch (Exception e) { e.printStackTrace(); }

		System.out.println("\n");
		System.out.println("- Storm's ARSFighter -");
		System.out.println("\n");
		System.out.println("NPC IDs: " + Arrays.toString(IDs));
		System.out.println("We are eating at Hits: " + eatAt);
		System.out.println("We are picking up these IDs: " + Arrays.toString(pickupIDs));
		System.out.println("\n");

		scriptRunning = true;
		scriptThread = new Thread(this);
		scriptThread.start();
	}

	public void stop() {
		System.gc();
		scriptRunning = false;
		debug("Stopped script.");
	}

	public void run() {
		
		
		int[] startExp = setStartExp();
		long start = System.currentTimeMillis();
	    
		/*
		 * UI START
		 */
		JFrame frame = new JFrame("EXP change");
		frame.setSize(500, 500);
		frame.setVisible(true);
		JButton jButton1 = new JButton("Screenshot");
		frame.setLayout(null);		
		JLabel timeRunning = new JLabel("Running for: " );
		JLabel attLabel = new JLabel("Attack Exp Gained: ");
		JLabel defLabel = new JLabel("Defense Exp Gained: ");
		JLabel strLabel = new JLabel("Strength Exp Gained: ");
		JLabel hitLabel = new JLabel("Hits Exp Gained: ");
		timeRunning.setBounds(15, 130, 300, 15);
		attLabel.setBounds(15, 10, 200, 15);
		defLabel.setBounds(15, 40, 200, 15);
		strLabel.setBounds(15, 70, 200, 15);
		hitLabel.setBounds(15, 100, 200, 15);
		frame.add(timeRunning);
		frame.add(attLabel);
		frame.add(defLabel);
		frame.add(strLabel);
		frame.add(hitLabel);
		/*
		 * UI END
		 */
		while (scriptRunning) {
			try {
				handleEvents();
				
				long elapsedTimeMillis = (System.currentTimeMillis()-start);
		        String timeRunningMillis = String.format("Running For: %d hour(s), %d minute(s), and %d second(s)", elapsedTimeMillis/(1000*60*60), (elapsedTimeMillis%(1000*60*60))/(1000*60), ((elapsedTimeMillis%(1000*60*60))%(1000*60))/1000);
					attLabel.setText("Attack Exp Gained: " + expChange("Attack", startExp));
					defLabel.setText("Defense Exp Gained: " + expChange("Defense", startExp));
					strLabel.setText("Strength Exp Gained: " + expChange("Strength", startExp));
					hitLabel.setText("Hits Exp Gained: " + expChange("Hits", startExp));
					timeRunning.setText(timeRunningMillis);
				if (getCurrentLevel()[3] <= eatAt && !inCombat()) {
					for (int i = 0; i < foodIDs.length; i++) {
						if(invContains(foodIDs[i])){
							useItem(i);
							wait(random(600, 700));
						}
					}
				}
				int[] door = getObjectById(64);
				if(door[0] != -1) {
					atObject(door[1], door[2]);
					wait(random(1500, 1700));
				} 
				

				if (getCurrentLevel()[3] <= eatAt && inCombat()) {
					walkTo(ourPlayerX(), ourPlayerY(), false);
					wait(620);
				}
				if (!inCombat() && walkback && (ourPlayerX() < walkbackXmin || ourPlayerX() > walkbackXmax ||
				ourPlayerY() < walkbackYmin || ourPlayerY() > walkbackYmax)) {
					walkToWait(origX, origY);
					wait(random(600, 900));
				}
				if (!inCombat()) {
					for (int i = 0; i < getGroundItemCount(); i++) {
						if (inArray(pickupIDs, getGroundItemID()[i])) {
							pickupItem(pickupIDs);
							wait(random(600, 700));
						}
					}
				}
				if (!inCombat()) {
					for (int b : boneIDs) {
						if (invContains(b)) {
							useItem(b);
							wait(random(600, 700));
						}
					}
				}
				if (!isSleeping() && !inCombat() && getCurrentLevel()[3] > eatAt) {
					attackNpc(IDs);
					wait(random(600, 700));
				}
				wait(50);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	public void handleEvents() throws Exception {
		if (welcomeBoxOpen())
			setWelcomeBox();
		if (!isLoggedIn())
			doLogin();
		if (getFatigue() > 90 && !isSleeping()) {
			wait(600);
			useItem(1263);
			wait(600);
		}
		if (getFatigueSleeping() < 10 && isSleeping())
			doSleeping();
		if (getFightMode() != fightMode)
			setFightMode();
	}
	
	public int expChange(String skill, int[] startExp){
		int[] currentExp = new int[17];
		int[] expDifference = new int[17];
		int val = -1;
		String[] statArray = {"Attack", "Defense", "Strength", "Hits", "Ranged", "Prayer", "Magic", "Cooking", "Woodcut", "Fletching", "Fishing", "Firemaking", "Crafting", "Smithing", "Mining", "Herblaw", "Agility"};
		

		for(int i = 0; i < 17; i++){
			if(statArray[i] == skill){
				return ((getCurrentExperience()[i] - startExp[i]) / 4);
			}
		}
		debug("You need to reference a skill by name!");
		debug("Right: Defense");
		debug("Wrong: defenSe, or, [1]");
		return -1;
		}
	
	public int[] setStartExp(){
		int[] startExp = new int[17];
		for(int i = 0; i < 17; i++){
			  startExp[i] = getCurrentExperience()[i];
			  wait(50);
		  }
		return startExp;
		
	}
	
}